package org.example.commonapi.util;


import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.example.commonapi.dto.LoginInfo;
import org.example.commonapi.util.redis.RedisService;
import org.example.commonapi.util.redis.UserPrefix;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

@Slf4j
@Component
public class JwtUtil {

    @Resource
    private RedisService redisService;

    //密钥
    private static final String Secret = "xienodesire";

    //失效时间
    private static final int EXPIRE = 1000 * 60 * 60 * 24 * 7;

    //alg
    private static final String ALG = "HS256";

    //签名
    private static final SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.HS256;

    //typ
    private static final String TYPE = "JWT";


    /**
     * 生成token
     * @return
     */
    public String createJwt(LoginInfo loginInfo){
        // JWT头部分信息【Header】
        Map<String, Object> header = new HashMap<>();
        header.put("alg", ALG);
        header.put("typ", TYPE);
        // 载核【Payload】
        Map<String, Object> payload = new HashMap<>();
        payload.put("id", loginInfo.getId());

        // 声明Token失效时间
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.SECOND,EXPIRE);

        // 生成Token
        String token = Jwts.builder()
                .setHeader(header)// 设置Header
                .setClaims(payload) // 设置载核
                .setExpiration(instance.getTime())// 设置生效时间
                .signWith(SIGNATURE_ALGORITHM,Secret)
                .compact(); // 压缩生成xxx.xxx.xxx
        System.out.println(token);
        return token;
    }


    /**
     * 解析token
     * @return
     */
    public LoginInfo parseJwt(String token){
        log.info("token解析中{}",token);
        //未登录
        if(StringUtils.isEmpty(token)){
            log.warn("未登录");
            return null;
        }
        //登录但过期，过期则为true
        if(isExpire(token)){
            log.warn("token已过期");
            return null;
        }
        // 解析Payload
        Claims claims =Jwts
                .parser()
                .setSigningKey(Secret)
                .parseClaimsJws(token)
                .getBody();

        //获取信息并且返回
        Long id=claims.get("id", Long.class);
        //查看token是否还存在
        if(redisService.get(UserPrefix.userKeyById,id.toString())==null){
            log.warn("token不存在");
            return null;
        }
        log.info("token解析成功");
        return new LoginInfo(claims);
    }


    /**
     * 判断token是否过期
     * @param token
     * @return
     */
    public boolean isExpire(String token){
        try {
            Jws<Claims> claimsJws = Jwts.parser().setSigningKey(Secret).parseClaimsJws(token);
            return claimsJws.getBody().getExpiration().before(new Date());
        } catch (ExpiredJwtException ex) {
            log.warn("Token已过期");
            return true;
        } catch (Exception ex) {
            log.warn("Token无效");
            return true;
        }
    }




}
